package com.yinhai.message.implement.wx.tool;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;

import com.yinhai.core.common.api.util.ValidateUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yinhai.message.api.exception.TMException;
import com.yinhai.message.core.util.HttpPoolManager;
/**
 * 
 * @author yanglq
 * 2017.4.24
 */
public class WxHttpsSendUtil {
	private static WxHttpsSendUtil wxHttps = null;
	public static WxHttpsSendUtil getInstance(){
		if (wxHttps == null) {
			synchronized (WxHttpsSendUtil.class) {
				if (wxHttps == null) {
					wxHttps = new WxHttpsSendUtil();
				}
			}
		}
		return wxHttps;
	}
	/**
	 * 获取token接口
	 */
	private String getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
	/**
	 * 拉微信用户信息接口
	 */
	private String getUserInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}";
	/**
	 * 主动推送信息接口
	 */
	private String sendMsgUrl = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}";
	/**
	 * 拉微信用户openid接口
	 */
	private String getUserOpenIdsUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}&next_openid={1}";
	/**
	 * 上传临时素材接口
	 */
	private String uploadUrl = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}";
	//http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=&type=image
	
	/**
	  * @desc 获取授权token
	  * @param appid
	  * @param secret
	  * @return
	  */
	 public String getAccessToken(String appid, String secret) throws Exception{
		String accessToken = null;
		try {
			String url = MessageFormat.format(getTokenUrl, appid, secret);
			JSONObject jo =JSON.parseObject(executeHttpGet(url));
			accessToken = jo.getString("access_token");
		} catch (Exception e) {
			throw new TMException("get access toekn exception----"+ e.getMessage());
		}
		return accessToken;
	 }
	 /**
	  * 获取用户openids
	  * @param access_token
	  * @return
	  */
	 public Set<String> getUsers(String access_token, String next_openid, int nowcount) throws Exception{
		String url = MessageFormat.format(getUserOpenIdsUrl, access_token, next_openid);
		Set<String> openIds = new HashSet<String>();
		Integer total = 0, count = 0;
		try {
			String result = executeHttpGet(url);
			JSONObject jo = JSON.parseObject(result);
			total = (Integer) jo.get("total");
			count = (Integer) jo.get("count");
			// 有关注者 json才有data参数
			if (count > 0) {
				JSONObject openIdData = (JSONObject) jo.get("data");
				JSONArray openIdArray = (JSONArray) openIdData.get("openid");
				for (int i = 0; i < openIdArray.size(); i++) {
					openIds.add((String) openIdArray.get(i));
				}
				// 每次最多拉取1万，total 超过1万，继续拉
				nowcount += count;
				if (nowcount < total) {
					 openIds.addAll(getUsers(access_token, jo.getString("next_openid"), nowcount));
				} 
			}
			
		} catch (Exception e) {
			throw new TMException("get getUsers  exception----"+ e.getMessage());
		}
		return openIds;
	}
	 /**
	  * 获取用户信息
	  * @param access_token
	  * @param openid
	  * @return
	  */
	 public String getUserInfo(String access_token, String openid) throws Exception{
		String userinfo = null;
		try {
			String url = MessageFormat.format(getUserInfoUrl, access_token, openid);
			userinfo = executeHttpGet(url);
		} catch (Exception e) {
			throw new TMException("get userinfo exception----"+ e.getMessage());
		}
		return userinfo;
	 }
	 /**
	  * 上传临时素材
	  * @param access_token
	  * @param ins
	  * @param type
	  * @return
	  */
	public String uploadFile(String access_token, InputStream ins, String type, String mimetype, String filename) throws Exception{
		String result = null;
		String mediaId = null;
		
		String url = MessageFormat.format(uploadUrl, access_token, type);
		CloseableHttpClient client = HttpPoolManager.getHttpClient();
		HttpPost post = new HttpPost(url);
		post.addHeader("Connection", "Keep-Alive");
		post.addHeader("Cache-Control", "no-cache");
		MultipartEntityBuilder reqEntitybuilder = MultipartEntityBuilder.create();
		reqEntitybuilder.addBinaryBody("media", getBytes(ins), ContentType.create(mimetype), filename);
		HttpEntity entity = reqEntitybuilder.build();
		post.setEntity(entity);
		CloseableHttpResponse response = client.execute(post);
		InputStream is = response.getEntity().getContent();
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();
		String line = null;
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		is.close();
		result = sb.toString();
		if (result.startsWith("{") && result.contains("media_id")) {
			JSONObject json = JSON.parseObject(result);
			mediaId = json.getString("media_id");
		} else {
			throw new TMException("uploadFile failed----" + result);
		}

		return mediaId;
	}
	public String uploadFile(String access_token, File file, String type, String mimetype, String filename) throws Exception{
		String result = null;
		String mediaId = null;
		
		String url = MessageFormat.format(uploadUrl, access_token, type);
		CloseableHttpClient client = HttpPoolManager.getHttpClient();
		HttpPost post = new HttpPost(url);
		post.addHeader("Connection", "Keep-Alive");
		post.addHeader("Cache-Control", "no-cache");
		MultipartEntityBuilder reqEntitybuilder = MultipartEntityBuilder.create();
		reqEntitybuilder.addBinaryBody("media", file, ContentType.create(mimetype), filename);
		HttpEntity entity = reqEntitybuilder.build();
		post.setEntity(entity);
		CloseableHttpResponse response = client.execute(post);
		InputStream is = response.getEntity().getContent();
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();
		String line = null;
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		is.close();
		result = sb.toString();
		if (result.startsWith("{") && result.contains("media_id")) {
			JSONObject json = JSON.parseObject(result);
			mediaId = json.getString("media_id");
		} else {
			throw new TMException("uploadFile failed----" + result);
		}

		return mediaId;
	}
	 /**
	  * @desc 发起HTTP GET请求返回数据
	  * @param url
	  * @return
	  * @throws IOException
	  * @throws ClientProtocolException
	  */
	String executeHttpGet(String url) throws Exception{
		CloseableHttpClient client = HttpPoolManager.getHttpClient();
		HttpGet get = new HttpGet(url);
		CloseableHttpResponse response = client.execute(get);
		InputStream is = response.getEntity().getContent();
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();
		String line = null;
		while ((line = reader.readLine()) != null) {
			sb.append(line);
		}
		is.close();
		return sb.toString();
	}
	/**
	 * 客服推送消息
	 * @param accessToken
	 * @param json
	 * @param contentType
	 */
	public void postMessage(String accessToken, String json,String contentType) throws Exception{
		String url = MessageFormat.format(sendMsgUrl, accessToken);
		CloseableHttpClient client = HttpPoolManager.getHttpClient();
		HttpPost post = new HttpPost(url);
		try {
			StringEntity s = new StringEntity(json, "utf-8");
			s.setContentType(contentType);
			post.setEntity(s);
			CloseableHttpResponse response = client.execute(post);
			InputStream is = response.getEntity().getContent();
			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
			is.close();
//			String result = sb.toString();
//			if(ValidateUtil.isNotEmpty(result)){
//				JSONObject jsonObject = JSONObject.parseObject(result);
//				Integer errorCode = (Integer) jsonObject.get("errcode");
//				if(0 != errorCode){
//					throw  new TMException(jsonObject.getString("errmsg"));
//				}
//			}
			System.out.println(sb.toString());
		} catch (Exception e) {
			throw new TMException("postMessage failed----"+ e.getMessage());
		}
	}
	
	public byte[] getBytes(InputStream ins){  
        byte[] buffer = null;  
        try {  
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);  
            byte[] b = new byte[1000];  
            int n;  
            while ((n = ins.read(b)) != -1) {  
                bos.write(b, 0, n);  
            }  
            ins.close();  
            bos.close();  
            buffer = bos.toByteArray();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return buffer;  
    }  
}
